package cn.jimmie.learn.viewArt.refreshview.core;

import android.view.MotionEvent;

/**
 * function :
 *
 * <p> Create Time:  2019年04月11日 22:22 </p>
 * <p> @author Jimmie.Qian  </p>
 */
public class TouchDispatcher {
    private static final float ELASTIC_COEFFICIENT = 1.5f;

    private RefreshSource mSource;
    private OnRefreshTouchListener mListener;

    private int downY, downX;
    private boolean isOverItem;

    public TouchDispatcher(RefreshSource source) {
        this.mSource = source;
    }

    public void setTouchListener(OnRefreshTouchListener listener) {
        this.mListener = listener;
    }

    /**
     * 处理 刷新布局 是否 拦截滑动事件
     */
    public boolean handleInterceptTouchEvent(MotionEvent e) {
        if (mSource.getState().getLoadState() != RefreshState.LoadState.IDLE) return false;

        int y = (int) e.getRawY();
        int x = (int) e.getRawX();
        boolean intercept = false;
        switch (e.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // 发生down事件时,记录y坐标, 此时没有拦截,
                // 所以down事件被子View消费, 改Layout的Down事件将不会被回调
                downY = y;
                downX = x;
                intercept = false;
                break;
            case MotionEvent.ACTION_MOVE:
                // deltaY > 0 是向下运动,< 0是向上运动
                int deltaY = y - downY;
                int deltaX = x - downX;

                // 1. 竖向滑动;  2. 下拉;   3. 在列表的首部; 4. 开启下拉刷新
                if (mSource.getState().isHeadViewEnable() &&
                        Math.abs(deltaX) < Math.abs(deltaY)
                        && mSource.isTopPosition()
                        && deltaY > 0) {
                    intercept = true;
                    // 下拉开始
                    mSource.getViewEvent().onHeaderRefreshPullDown();
                }
                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        return intercept;
    }

    /**
     * 处理 触摸事件
     */
    public boolean handleTouchEvent(MotionEvent event) {
        int headerHeight = mSource.getHeaderHeight();
        int topMargin = mSource.getHeaderTopMargin();

        switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE:

                float moveY = event.getRawY();
                int distance = (int) (moveY - downY);
                // 如果手指是下滑状态，并且下拉头是完全隐藏的，就屏蔽下拉事件
                if (distance <= 0 && topMargin <= -headerHeight) {
                    return false;
                }
                if (!isOverItem && topMargin >= 0) {
                    mSource.getViewEvent().onHeaderRefreshFullItem();
                    isOverItem = true;
                }
                // 弹性系数
                if (topMargin >= headerHeight * ELASTIC_COEFFICIENT) break;
                if (mListener != null) mListener.onHeaderTouchPulling(distance);
                break;

            case MotionEvent.ACTION_OUTSIDE:
            case MotionEvent.ACTION_POINTER_UP:
            case MotionEvent.ACTION_UP:
                // 缓慢移动时, 手抬起被判断是 CANCEL
            case MotionEvent.ACTION_CANCEL:

                isOverItem = false;
                if (topMargin == 0 || topMargin == -headerHeight) {
                    mSource.getState().setLoadState(RefreshState.LoadState.IDLE);
                    break;
                }
                boolean needRefresh = topMargin > 0;

                mSource.getViewEvent().onHeaderRefreshRelease(needRefresh);
                if (mListener != null) mListener.onHeaderTouchRelease(needRefresh);

                if (needRefresh) {
                    mSource.getState().setLoadState(RefreshState.LoadState.REFRESHING);
                } else mSource.getState().setLoadState(RefreshState.LoadState.IDLE);

                break;
        }
        return true;
    }

    public interface OnRefreshTouchListener {
        void onHeaderTouchPulling(int distance);

        void onHeaderTouchRelease(boolean needRefresh);
    }
}
